using System.Text;
using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using Csla.Validation;
using BA.DAL;
using BA;


namespace BlazeApps.Library.Forum
{ 
	[Serializable()] 
	public class Board : Csla.BusinessBase<Board>
	{
        private BlazeApps.Library.ConfigSettings Config = new BlazeApps.Library.ConfigSettings();
        private BA.DAL.DBUtility DAL = new BA.DAL.DBUtility();
        private Procedures Procs = new Procedures();

		#region Business Properties and Methods

		//declare members
		private Guid _boardID = Guid.NewGuid();
		private string _boardName = string.Empty;
        private int _sortOrder = 0;
        private Guid _lastUserID = Guid.Empty;

		[System.ComponentModel.DataObjectField(true, false)]
		public Guid BoardID
		{
			get
			{
				CanReadProperty("BoardID", true);
				return _boardID;
			}
		}

		public string BoardName
		{
			get
			{
				CanReadProperty("BoardName", true);
				return _boardName;
			}
			set
			{
				CanWriteProperty("BoardName", true);
				if (value == null) value = string.Empty;
				if (!_boardName.Equals(value))
				{
					_boardName = value;
					PropertyHasChanged("BoardName");
				}
			}
		}

        public int SortOrder
        {
            get
            {
                CanReadProperty("SortOrder", true);
                return _sortOrder;
            }
            set
            {
                CanWriteProperty("SortOrder", true);
                if (!_sortOrder.Equals(value))
                {
                    _sortOrder = value;
                    PropertyHasChanged("SortOrder");
                }
            }
        }

        public Guid LastUserID
        {
            get
            {
                CanReadProperty("LastUserID", true);
                return _lastUserID;
            }
            set
            {
                CanWriteProperty("LastUserID", true);
                if (!_lastUserID.Equals(value))
                {
                    _lastUserID = value;
                    PropertyHasChanged("LastUserID");
                }
            }
        }
 
		protected override object GetIdValue()
		{
			return _boardID;
		}

		#endregion //Business Properties and Methods

		#region Validation Rules
		private void AddCustomRules()
		{
			//add custom/non-generated rules here...
		}

		private void AddCommonRules()
		{
			//
			// BoardName
			//
			ValidationRules.AddRule(CommonRules.StringRequired, "BoardName");
			ValidationRules.AddRule(CommonRules.StringMaxLength, new CommonRules.MaxLengthRuleArgs("BoardName", 200));
		}

		protected override void AddBusinessRules()
		{
			AddCommonRules();
			AddCustomRules();
		}
		#endregion //Validation Rules

		#region Authorization Rules
		protected override void AddAuthorizationRules()
		{
			//TODO: Define authorization rules in Board
			//AuthorizationRules.AllowRead("BoardID", "BoardReadGroup");
			//AuthorizationRules.AllowRead("BoardName", "BoardReadGroup");

			//AuthorizationRules.AllowWrite("BoardName", "BoardWriteGroup");
		}


		public static bool CanGetObject()
		{
			//TODO: Define CanGetObject permission in Board
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("BoardViewGroup"))
			//	return true;
			//return false;
		}

		public static bool CanAddObject()
		{
			//TODO: Define CanAddObject permission in Board
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("BoardAddGroup"))
			//	return true;
			//return false;
		}

		public static bool CanEditObject()
		{
			//TODO: Define CanEditObject permission in Board
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("BoardEditGroup"))
			//	return true;
			//return false;
		}

		public static bool CanDeleteObject()
		{
			//TODO: Define CanDeleteObject permission in Board
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("BoardDeleteGroup"))
			//	return true;
			//return false;
		}
		#endregion //Authorization Rules

		#region Factory Methods
		private Board()
		{ /* require use of factory method */ }

		public static Board NewBoard()
		{
			if (!CanAddObject())
				throw new System.Security.SecurityException("User not authorized to add a Board");
			return DataPortal.Create<Board>();
		}

		public static Board GetBoard(Guid boardID)
		{
			if (!CanGetObject())
				throw new System.Security.SecurityException("User not authorized to view a Board");
			return DataPortal.Fetch<Board>(new Criteria(boardID));
		}

		public static void DeleteBoard(Guid boardID)
		{
			if (!CanDeleteObject())
				throw new System.Security.SecurityException("User not authorized to remove a Board");
			DataPortal.Delete(new Criteria(boardID));
		}

		public override Board Save()
		{
			if (IsDeleted && !CanDeleteObject())
				throw new System.Security.SecurityException("User not authorized to remove a Board");
			else if (IsNew && !CanAddObject())
				throw new System.Security.SecurityException("User not authorized to add a Board");
			else if (!CanEditObject())
				throw new System.Security.SecurityException("User not authorized to update a Board");

			return base.Save();
		}

		#endregion //Factory Methods

		#region Data Access

		#region Criteria

		[Serializable()]
		private class Criteria
		{
			public Guid BoardID;

			public Criteria(Guid boardID)
			{
				this.BoardID = boardID;
			}
		}

		#endregion //Criteria

		#region Data Access - Create
		[RunLocal]
		protected override void DataPortal_Create()
		{
			ValidationRules.CheckRules();
		}

		#endregion //Data Access - Create

		#region Data Access - Fetch
        private void DataPortal_Fetch(Criteria criteria)
        {
            ExecuteFetch(criteria);
        }

        private void ExecuteFetch(Criteria criteria)
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            DAL.AddParameter("@BoardID", criteria.BoardID);

            using(SafeDataReader dr = new SafeDataReader(DAL.ExecuteReader(Procs.GetBoardByBoardID.ToString().Trim(), CommandType.Text, ConnectionState.Open)))
            {
                FetchObject(dr);
                ValidationRules.CheckRules();

                //load child object(s)
                FetchChildren(dr);
            }
        }

		private void FetchObject(SafeDataReader dr)
		{
			dr.Read();
			_boardID = dr.GetGuid("BoardID");
			_boardName = dr.GetString("BoardName");
            _sortOrder = dr.GetInt32("SortOrder");
            _lastUserID = dr.GetGuid("LastUserID");
		}

		private void FetchChildren(SafeDataReader dr)
		{
		}
		#endregion //Data Access - Fetch

		#region Data Access - Insert
        protected override void DataPortal_Insert()
        {
            ExecuteInsert();
        }

        private void ExecuteInsert()
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddInsertParameters(ref DAL);

            DAL.ExecuteNonQuery(Procs.InsertBoard.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddInsertParameters(ref BA.DAL.DBUtility DAL)
		{
			DAL.AddParameter("@BoardID", _boardID);
			DAL.AddParameter("@BoardName", _boardName);
            DAL.AddParameter("@SortOrder", _sortOrder);
            DAL.AddParameter("@LastUserID", _lastUserID);
		}
		#endregion //Data Access - Insert

		#region Data Access - Update
        protected override void DataPortal_Update()
        {
            if (base.IsDirty)
            {
                ExecuteUpdate();
            }
        }

        private void ExecuteUpdate()
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddUpdateParameters(ref DAL);

            DAL.ExecuteNonQuery(Procs.UpdateBoard.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddUpdateParameters(ref BA.DAL.DBUtility DAL)
		{
			DAL.AddParameter("@BoardID", _boardID);
			DAL.AddParameter("@BoardName", _boardName);
            DAL.AddParameter("@SortOrder", _sortOrder);
            DAL.AddParameter("@LastUserID", _lastUserID);
		}

		private void UpdateChildren(SqlConnection cn)
		{
		}
		#endregion //Data Access - Update

		#region Data Access - Delete
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(new Criteria(_boardID));
        }

        private void DataPortal_Delete(Criteria criteria)
        {
            ExecuteDelete(criteria);
            DeleteModerators(criteria);
        }

        private void ExecuteDelete(Criteria criteria)
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddDeleteParameters(ref DAL, criteria);

            DAL.ExecuteNonQuery(Procs.DeleteBoard.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void DeleteModerators(Criteria criteria)
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddDeleteParameters(ref DAL, criteria);

            DAL.ExecuteNonQuery(Procs.DeleteForumModeratorsByBoardID.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddDeleteParameters(ref BA.DAL.DBUtility DAL, Criteria criteria)
        {
            DAL.AddParameter("@BoardID", criteria.BoardID);
        }

		#endregion //Data Access - Delete
		#endregion //Data Access
	}
}
